/* * Copyright 2010-2017 Norwegian Agency for Public Management and eGovernment (Difi) * * Licensed under the EUPL, Version 1.1 or – as soon they * will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * * You may not use this work except in compliance with the Licence. * * You may obtain a copy of the Licence at: * * https://joinup.ec.europa.eu/community/eupl/og_page/eupl * * Unless required by applicable law or agreed to in * writing, software distributed under the Licence is * distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the Licence for the specific language governing * permissions and limitations under the Licence. */ package no.difi.oxalis.statistics.security; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import javax.crypto.*; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.nio.charset.Charset; import java.security.*; import static org.testng.Assert.assertEquals; /** * @author steinar * Date: 29.04.13 * Time: 09:51 */ public class EncryptionTest { private KeyPair keyPair; private SecretKey secretKey; @BeforeClass public void createKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); // Medium security is fine keyPair = keyPairGenerator.generateKeyPair(); KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(new SecureRandom()); secretKey = keyGenerator.generateKey(); } @Test() public void encryptData() throws Exception { String plainText = "Hello world"; byte[] encryptedBytes = encrypt(keyPair, plainText); String decryptedPlainText = decrypt(keyPair, encryptedBytes); assertEquals(decryptedPlainText, plainText); } @Test public void encryptAndDecryptFile() throws Exception { File file = File.createTempFile("oxalis", ".data"); // Writes encrypted data into file Cipher encryptionCipher = Cipher.getInstance("DES/CFB8/NoPadding"); encryptionCipher.init(Cipher.ENCRYPT_MODE, secretKey); CipherOutputStream cipherOutputStream = new CipherOutputStream(new FileOutputStream(file), encryptionCipher); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(cipherOutputStream, Charset.forName("UTF-8")); String plainText = "Hello world"; outputStreamWriter.write(plainText); outputStreamWriter.close(); // Reads and decrypts data from a file ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); Cipher cipher = Cipher.getInstance("DES/CFB8/NoPadding"); AlgorithmParameters parameters = encryptionCipher.getParameters(); System.err.println(parameters.toString()); cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters); Cipher symmetricCipher = cipher; CipherInputStream cipherInputStream = new CipherInputStream(new FileInputStream(file), symmetricCipher); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cipherInputStream, Charset.forName("UTF-8"))); String decryptedText = bufferedReader.readLine(); assertEquals(decryptedText, plainText); file.delete(); } /** * Experimental test method. Does not test any part of the system * * @throws Exception */ @Test public void encryptDataWithWrappedKey() throws Exception { // Creates the shared key to be used for encrypting the data KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); Key sharedKey = keyGenerator.generateKey(); // Wraps the shared key within an asymmetric key String password = "The quick brown fox jumped over the lazy dog"; byte[] salt = {0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x06, 0x08}; PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 20); PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey passwordKey = kf.generateSecret(pbeKeySpec); Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); cipher.init(Cipher.WRAP_MODE, passwordKey, pbeParameterSpec); byte[] wrappedSharedKey = cipher.wrap(sharedKey); // Encrypt some data with shared key cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, sharedKey); String plainText = "Hello world"; byte[] input = plainText.getBytes(); byte[] encrypted = cipher.doFinal(input); // Read the wrapped key and the encrypted data // First; unwrap the key cipher = Cipher.getInstance("PBEWithMD5AndDES"); // TODO: pass the parameters of the wrappedSharedKey cipher.init(Cipher.UNWRAP_MODE, passwordKey, pbeParameterSpec); Key unwrappedKey = cipher.unwrap(wrappedSharedKey, "AES", Cipher.SECRET_KEY); // Decrypt the data cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, unwrappedKey); String newData = new String(cipher.doFinal(encrypted)); assertEquals(newData, plainText); } @Test public void createAsymmetricKeyPair() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); KeyPair pair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = pair.getPublic(); System.err.println("Algorithm:" + publicKey.getAlgorithm()); System.err.println("Format" + publicKey.getFormat()); byte[] encoded = publicKey.getEncoded(); for (int i = 0; i < encoded.length; i++) { byte b = encoded[i]; } } /** * Encrypts something with AES, transforms the key into a key specification, recreates the key and decrypts * the encrypted contents. * * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws UnsupportedEncodingException * @throws BadPaddingException * @throws IllegalBlockSizeException */ @Test public void encryptAndDecryptWithSymmetricKey() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecretKey key = keyGenerator.generateKey(); System.err.println("Algorithm:" + key.getAlgorithm()); System.err.println("Format:" + key.getFormat()); // Transforms the secret key (symmetric) into a secret key specification SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), "AES"); Cipher encryptionCipher = Cipher.getInstance("AES"); encryptionCipher.init(Cipher.ENCRYPT_MODE, key); String plainText = "Hello world"; byte[] encryptedBytes = encryptionCipher.doFinal(plainText.getBytes("UTF-8")); Cipher decryptionCipher = Cipher.getInstance("AES"); decryptionCipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] decryptedBytes = decryptionCipher.doFinal(encryptedBytes); String decryptedText = new String(decryptedBytes, Charset.forName("UTF-8")); assertEquals(decryptedText, plainText); } @Test public void holdEncryptedBytes() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecretKey key = keyGenerator.generateKey(); } private Cipher getSymmetricCipher(int mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { Cipher cipher = Cipher.getInstance("DES/CFB8/NoPadding"); cipher.init(mode, secretKey); return cipher; } private String decrypt(KeyPair keyPair, byte[] encryptedBytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = getCipher(); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] bytes = cipher.doFinal(encryptedBytes); return new String(bytes, Charset.forName("UTF-8")); } private Cipher getCipher() throws NoSuchAlgorithmException, NoSuchPaddingException { return Cipher.getInstance("RSA"); } private byte[] encrypt(KeyPair keyPair, String plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = getCipher(); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] bytes = cipher.doFinal(plainText.getBytes()); return bytes; } }